package com.geeke.sys.service;

import java.util.List;
import java.util.Map;

import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.geeke.common.data.PageRequest;
import com.geeke.common.data.Parameter;
import com.geeke.common.service.CrudService;
import com.geeke.config.exception.CommonJsonException;
import com.geeke.sys.dao.UserDao;
import com.geeke.sys.dao.UserPostDao;
import com.geeke.sys.dao.UserRoleDao;
import com.geeke.sys.entity.User;
import com.geeke.sys.entity.UserPost;
import com.geeke.sys.entity.UserRole;
import com.geeke.utils.Reflections;
import com.geeke.utils.ResultUtil;
import com.geeke.utils.SessionUtils;
import com.geeke.utils.StringUtils;
import com.geeke.utils.constants.ErrorEnum;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * 用户管理Service
 * @author
 * @version
 */

@Service("userService")
@Transactional(readOnly = true)
public class UserService extends CrudService<UserDao, User> {

    @Autowired
    private UserRoleDao userRoleDao;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private UserPostDao userPostDao;

    @Autowired
    private UserPostService userPostService;

    @Override
    public User get(String id) {
        User user = super.get(id);

        List<Parameter> params = null;
        PageRequest pageRequest;

        /*获取子表列表   用户角色*/
        params = Lists.newArrayList();

        params.add(new Parameter("userRole.user_id", "=", user.getId()));
        pageRequest = new PageRequest(params);
        user.setUserRoleList(userRoleDao.listAll(pageRequest));

        /*获取子表列表   用户岗位*/
        params = Lists.newArrayList();

        params.add(new Parameter("userPost.user_id", "=", user.getId()));
        pageRequest = new PageRequest(params);
        user.setUserPostList(userPostDao.listAll(pageRequest));

        return user;
    }

    @Override
    @CacheEvict(cacheNames = {"resourcePermission"}, key = "'user-' + #user.id + '_router-*'")
    public User save(User user) {
        return save(user, false);
    }

    /**
     * 保存用户
     * @param user
     * @param noSamePwd  密码不能与上次相同
     * @return
     */
    @Transactional(readOnly = false)
    @CacheEvict(cacheNames = {"resourcePermission"}, key = "'user-' + #user.id + '_router-*'")
    public User save(User user, boolean noSamePwd) {

        // 重复性检查
        List<Parameter> params = Lists.newArrayList();

        params.add(new Parameter("user.login_name", "=", user.getLoginName()));
        params.add(new Parameter("user.del_flag", "=", user.getDelFlag()));
        if(!StringUtils.isBlank(user.getId())) {
            params.add(new Parameter("user.id", "<>", user.getId()));
        }
        if(this.dao.count(new PageRequest(params)) > 0) {
            throw new CommonJsonException(ResultUtil.warningJson(ErrorEnum.E_50001, "已存在相同登录名"));
        }

        params.clear();
        params.add(new Parameter("user.phone", "=", user.getPhone()));
        params.add(new Parameter("user.del_flag", "=", user.getDelFlag()));
        if(!StringUtils.isBlank(user.getId())) {
            params.add(new Parameter("user.id", "<>", user.getId()));
        }
        if(this.dao.count(new PageRequest(params)) > 0) {
            throw new CommonJsonException(ResultUtil.warningJson(ErrorEnum.E_50001, "已存在相同登录名"));
        }

        User userTemp = super.save(user);

        // 加密字段处理
        if (StringUtils.isNoneBlank(userTemp.getId())) {
            // 设置加密字段  密码
            if (user.getLoginPasswordUpdate()) {
                this.changeLoginPassword(userTemp.getId(), user.getLoginPassword(), noSamePwd);
            }
        }

        /* 保存子表数据     用户角色 */
        saveUserRoleList(userTemp);

        /* 保存子表数据     用户岗位 */
        saveUserPostList(userTemp);

        return userTemp;
    }

    /**
     * 删除
     * @param user
     */
    @Override
    @Transactional(readOnly = false)
    public int delete(User user) {
        List<Parameter> params = null;
        PageRequest pageRequest;

        /* 处理子表     用户角色 */
        params = Lists.newArrayList();

        params.add(new Parameter("user_id", "=", user.getId()));
        pageRequest = new PageRequest(params);
        user.setUserRoleList(userRoleDao.listAll(pageRequest));

        if (user.getUserRoleList() != null && user.getUserRoleList().size() > 0) {
            userRoleService.bulkDelete(user.getUserRoleList());
        }

        /* 处理子表     用户岗位 */
        params = Lists.newArrayList();

        params.add(new Parameter("user_id", "=", user.getId()));
        pageRequest = new PageRequest(params);
        user.setUserPostList(userPostDao.listAll(pageRequest));

        if (user.getUserPostList() != null && user.getUserPostList().size() > 0) {
            userPostService.bulkDelete(user.getUserPostList());
        }

        int rows = super.delete(user);
        return rows;
    }

    /**
     * 批量删除
     * @param userList
     */
    @Override
    @Transactional(readOnly = false)
    public int bulkDelete(List<User> userList) {
        for (User user : userList) {
            delete(user);
        }

        return userList.size();
    }

    // 修改加密字段

    /**
     * 修改 密码
     */
    public int changeLoginPassword(String id, String pass) {
        return changeLoginPassword(id, pass, false);
    }

    @Transactional(readOnly = false)
    public int changeLoginPassword(String id, String pass, boolean noSamePwd) {
        // Md5密码
        Md5Hash md5 = new Md5Hash(pass, id, 6);
        String md5Password = md5.toHex();
        if(noSamePwd) {
            User u = this.get(id);
            if(md5Password.equals(u.getLoginPassword())) {
                throw new CommonJsonException(ResultUtil.warningJson(ErrorEnum.E_10014));
            }
        }
        int rows = dao.updateLoginPassword(id, md5Password);
        return rows;
    }

    /**
     * 激活当前用户
     * @return
     */
    @Transactional(readOnly = false)
    public int activeCurrentUser() {
        User currentUser = SessionUtils.getUser();
        int rows = dao.activeUser(currentUser.getId());
        return rows;
    }
    /* 保存子表数据     用户角色 */
    private void saveUserRoleList(User user) {
        List<Parameter> params = Lists.newArrayList();

        params.add(new Parameter("user_id", "=", user.getId()));
        PageRequest pageRequest = new PageRequest(params);
        List<UserRole> list_UserRole = userRoleDao.listAll(pageRequest);

        List<UserRole> deletes = Lists.newArrayList(); // 删除列表
        List<UserRole> inserts = Lists.newArrayList(); // 添加列表
        List<UserRole> updates = Lists.newArrayList(); // 更新列表
        for (UserRole userRoleSaved : list_UserRole) {
            boolean found = false;
            for (UserRole userRole : user.getUserRoleList()) {
                if (userRoleSaved.getId().equals(userRole.getId())) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                deletes.add(userRoleSaved);
            }
        }
        if (deletes.size() > 0) {
            userRoleService.bulkDelete(deletes);
        }
        for (UserRole userRole : user.getUserRoleList()) {
            if (StringUtils.isBlank(userRole.getId())) {
                userRole.setUser(user);

                inserts.add(userRole);
            } else {
                updates.add(userRole);
            }
        }
        if (updates.size() > 0) {
            userRoleService.bulkUpdate(updates);
        }
        if (inserts.size() > 0) {
            userRoleService.bulkInsert(inserts);
        }
    }
    /* 保存子表数据     用户岗位 */
    private void saveUserPostList(User user) {
        List<Parameter> params = Lists.newArrayList();

        params.add(new Parameter("user_id", "=", user.getId()));
        PageRequest pageRequest = new PageRequest(params);
        List<UserPost> list_UserPost = userPostDao.listAll(pageRequest);

        List<UserPost> deletes = Lists.newArrayList(); // 删除列表
        List<UserPost> inserts = Lists.newArrayList(); // 添加列表
        List<UserPost> updates = Lists.newArrayList(); // 更新列表
        for (UserPost userPostSaved : list_UserPost) {
            boolean found = false;
            for (UserPost userPost : user.getUserPostList()) {
                if (userPostSaved.getId().equals(userPost.getId())) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                deletes.add(userPostSaved);
            }
        }
        if (deletes.size() > 0) {
            userPostService.bulkDelete(deletes);
        }
        for (UserPost userPost : user.getUserPostList()) {
            if (StringUtils.isBlank(userPost.getId())) {
                userPost.setUser(user);

                inserts.add(userPost);
            } else {
                updates.add(userPost);
            }
        }
        if (updates.size() > 0) {
            userPostService.bulkUpdate(updates);
        }
        if (inserts.size() > 0) {
            userPostService.bulkInsert(inserts);
        }
    }
}
